import logging

from agent.common.system import sysCommand
from agent.feature.base import Feature
from agent.common.netinfo import NetInfo
from agent.common.config import Config

logger = logging.getLogger('common')

class XPS(Feature):
    __domain__ = "net"
    __feature__ = "XPS"
    
    def __init__(self) -> None:
        super().__init__(self.__domain__, self.__feature__)
        self.net_info = NetInfo()
        assert self.net_info.tx_queue.__len__() != 0
    
    def auto_setting(self):
        logger.info("auto setting xps by script set_xps_rps.sh")
        sysCommand(
            "sh set_xps_rps.sh {} xps enable".format(self.net_info.dev_name),
            cwd = Config.SCRIPTS_PATH,
            log = True
        )
    
    def set_value(self, value):
        if type(value) == str and value == "auto":
            self.auto_setting()
            
        elif type(value) == str:
            xps_bingding_schema = self.net_info.get_queue_binding_schema(binding_type = value)
            for queue_id, core_code in xps_bingding_schema.items():
                sysCommand("echo {} > /sys/class/net/{}/queues/{}/xps_cpus".format(
                            core_code, self.net_info.dev_name, queue_id))
                
        else:
            xps_bingding_schema = value
            for queue_id, core_code in xps_bingding_schema.items():
                sysCommand("echo {} > /sys/class/net/{}/queues/{}/xps_cpus".format(
                            core_code, self.net_info.dev_name, queue_id))

    def get_value(self):
        xps_bingding_schema = {}
        for queue_id in self.net_info.tx_queue:
            xps_bingding_schema[queue_id] = sysCommand(
                "cat /sys/class/net/{}/queues/{}/xps_cpus".format(self.net_info.dev_name, queue_id))
        return xps_bingding_schema

if __name__ == "__main__":
    handler = XPS()
    handler.backup()
    handler.set_value("all")
    handler.set_value("off")
    handler.set_value("different")
    handler.set_value("disperse")
    handler.set_value("auto")
    handler.rollback()